openai-agents-v2: use genai-utils for env var constant, histogram factories, and meter_provider#4456
Conversation
…nd meter_provider Three improvements to align with opentelemetry-util-genai: 1. Import OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT from opentelemetry.util.genai.environment_variables instead of re-defining it locally in __init__.py. 2. Add meter_provider parameter to GenAISemanticProcessor and thread it through _init_metrics(), fixing the bug where a caller-supplied MeterProvider was silently ignored. 3. Replace inline create_histogram() calls with create_duration_histogram() and create_token_histogram() from opentelemetry.util.genai.instruments, which adds the semconv-specified explicit bucket boundaries that were previously missing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Aligns opentelemetry-instrumentation-openai-agents-v2 with opentelemetry-util-genai by reusing shared env var/constants and instrument factories, and by correctly honoring a caller-provided MeterProvider when creating metrics instruments.
Changes:
- Import
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENTfromopentelemetry.util.genai.environment_variables(single source of truth). - Thread an optional
meter_providerintoGenAISemanticProcessormetrics initialization and pass the package__version__toget_meter(). - Replace inline histogram creation with
create_duration_histogram/create_token_histogramto apply semconv bucket boundaries.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py | Adds meter_provider support for get_meter, uses package version, and switches to genai-utils histogram factories. |
| instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/init.py | Uses shared env var constant and passes meter_provider through instrumentor kwargs to the span processor. |
| instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md | Documents the alignment changes under Unreleased. |
| self._meter = get_meter( | ||
| "opentelemetry.instrumentation.openai_agents", "0.1.0" | ||
| ) | ||
|
|
||
| # Operation duration histogram | ||
| self._duration_histogram = self._meter.create_histogram( | ||
| name="gen_ai.client.operation.duration", | ||
| description="GenAI operation duration", | ||
| unit="s", | ||
| ) | ||
|
|
||
| # Token usage histogram | ||
| self._token_usage_histogram = self._meter.create_histogram( | ||
| name="gen_ai.client.token.usage", | ||
| description="Number of input and output tokens used", | ||
| unit="{token}", | ||
| "opentelemetry.instrumentation.openai_agents", | ||
| __version__, | ||
| meter_provider, | ||
| ) |
There was a problem hiding this comment.
The new meter_provider plumbing fixes an important behavior change (caller-supplied providers were previously ignored), but it doesn’t look like there’s a unit test asserting the passed meter_provider is actually used by get_meter(...). Adding a small test with a stub MeterProvider (tracking get_meter calls) would prevent regressions.
| self._meter = None | ||
| self._duration_histogram: Optional[Histogram] = None | ||
| self._token_usage_histogram: Optional[Histogram] = None | ||
| self._duration_histogram: Optional[object] = None | ||
| self._token_usage_histogram: Optional[object] = None |
There was a problem hiding this comment.
_duration_histogram and _token_usage_histogram were widened from Optional[Histogram] to Optional[object], which loses type safety even though create_duration_histogram/create_token_histogram return Histogram. Consider importing Histogram and keeping these attributes typed as Optional[Histogram] (or a more specific protocol) so static checkers can validate .record() usage.
Summary
Three improvements to align
opentelemetry-instrumentation-openai-agents-v2withopentelemetry-util-genai:Changes
1. Env var constant — single source of truth
Remove
_CONTENT_CAPTURE_ENV = "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"from__init__.pyand import the constant fromopentelemetry.util.genai.environment_variables.2. Fix silently-ignored
meter_providerGenAISemanticProcessor._init_metrics()previously calledget_meter(...)without any provider, so a caller-suppliedmeter_providerwas silently ignored. This PR:meter_provider: Optional[MeterProvider] = NonetoGenAISemanticProcessor.__init___init_metrics(meter_provider)get_meter()along with the package's actual__version__(was hardcoded as"0.1.0")3. Semconv bucket boundaries via genai-utils histogram factories
Replace inline
meter.create_histogram()calls withcreate_duration_histogram(meter)andcreate_token_histogram(meter)fromopentelemetry.util.genai.instruments. This adds the semconv-specified explicit bucket boundaries that were previously missing from the agent's metrics.Testing
All 103 existing tests pass.